from scipy.optimize import linprog
import numpy as np

# 目标函数：最小化成本
cost_per_kg = np.array([8.6, 6.0, 8.9, 5.7, 8.8])
c = cost_per_kg

# 约束条件：
# 1. 总重量为 100 kg
A_eq = np.array([[1, 1, 1, 1, 1]])
b_eq = np.array([100])

# 2. 锡和锌的比例约束: -120x1 - 40x2 + 40x3 - 10x4 + 70x5 = 0
A_eq = np.vstack([A_eq, [-120, -40, 40, -10, 70]])
b_eq = np.hstack([b_eq, [0]])

# 3. 锌和铜的比例约束: 280x1 - 40x2 + 40x3 - 110x4 - 30x5 = 0
A_eq = np.vstack([A_eq, [280, -40, 40, -110, -30]])
b_eq = np.hstack([b_eq, [0]])

# 各合金用量 >= 0
bounds = [(0, None)] * 5

# 利用单纯形法求解模型
res = linprog(c, A_eq=A_eq, b_eq=b_eq, bounds=bounds, method='simplex')

print("(2) 利用单纯形法求解模型，并写出分配方案 (严格满足比例):")
if res.success:
    print("最优解找到")
    print("各合金用量 (kg):")
    print(f"合金 1: {res.x[0]:.2f}")
    print(f"合金 2: {res.x[1]:.2f}")
    print(f"合金 3: {res.x[2]:.2f}")
    print(f"合金 4: {res.x[3]:.2f}")
    print(f"合金 5: {res.x[4]:.2f}")
    print(f"总成本: {res.fun:.2f} 元")

    # 计算最终合金的成分比例进行验证
    total_weight = np.sum(res.x)
    tin_content = (30*res.x[0] + 10*res.x[1] + 50*res.x[2] + 10*res.x[3] + 50*res.x[4])
    zinc_content = (60*res.x[0] + 20*res.x[1] + 20*res.x[2] + 10*res.x[3] + 10*res.x[4])
    copper_content = (10*res.x[0] + 70*res.x[1] + 30*res.x[2] + 80*res.x[3] + 40*res.x[4])

    print("\n验证合金成分比例:")
    print(f"锡含量: {tin_content:.2f}")
    print(f"锌含量: {zinc_content:.2f}")
    print(f"铜含量: {copper_content:.2f}")

    # 计算比例并进行比较
    ratio = np.array([tin_content, zinc_content, copper_content])
    common_divisor = np.gcd.reduce(ratio.astype(int))
    normalized_ratio = ratio / common_divisor
    print(f"比例 (锡:锌:铜): {normalized_ratio[0]:.1f}:{normalized_ratio[1]:.1f}:{normalized_ratio[2]:.1f}")

else:
    print("未找到最优解")
    print(res.message)